package org.ligson.fwc.core.service.impl;


import org.ligson.fwc.core.dao.BaseDao;
import org.ligson.fwc.core.entity.BasicEntity;
import org.ligson.fwc.core.entity.Pagination;
import org.ligson.fwc.core.exception.EntityValidException;
import org.ligson.fwc.core.id.IdGenerator;
import org.ligson.fwc.core.service.BaseService;
import org.springframework.cglib.core.ReflectUtils;

import java.io.Serializable;
import java.lang.reflect.Method;

/**
 * Created by ligson on 2016/3/21.
 * 接口实现
 */
public abstract class BaseServiceImpl<T extends BasicEntity, PK extends Serializable> implements BaseService<T, PK> {

    public abstract BaseDao<T, PK> getDao();

    @Override
    public T get(PK primaryKey) {
        return getDao().get(primaryKey);
    }

    @Override
    @SuppressWarnings(value = "unchecked")
    public Pagination<T> findAllBy(T o) {
        return getDao().getPaginationList(o);
    }

    @Override
    @SuppressWarnings(value = "unchecked")
    public int countBy(T t) {
        return getDao().countBy(t);
    }

    @Override
    public void delete(T t) {
        getDao().delete(t);
    }

    @Override
    public void update(T t) {
        int n = getDao().update(t);
        if (n < 0) {
            throw new EntityValidException(t);
        }
    }

    @Override
    public void add(T t) {
        IdGenerator idGenerator = t.idGenerator();
        String primaryKey = t.primaryKey();
        String methodName = "set" + Character.toUpperCase(primaryKey.charAt(0)) + primaryKey.substring(1);
        Method method;
        try {
            method = ReflectUtils.findDeclaredMethod(t.getClass(), methodName, new Class[]{t.primaryKeyType()});
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
        try {
            method.invoke(t, idGenerator.generatorId(getDao()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Integer integer = getDao().insert(t);
        if (integer < 0) {
            throw new EntityValidException(t);
        }
    }

    @Override
    public void deleteByPrimaryKey(PK pk) {
        T t = getDao().get(pk);
        int n = getDao().deleteByPrimaryKey(t);
        if (n < 0) {
            throw new EntityValidException(t);
        }
    }

    @Override
    public void updateByPrimaryKey(T t) {
        int n = getDao().updateByPrimaryKey(t);
        if (n < 0) {
            throw new EntityValidException(t);
        }
    }

    @Override
    public T findBy(T t) {
        return getDao().findBy(t);
    }

    @Override
    public Pagination<T> likeAllBy(T entityCond) {
        return getDao().likeBy(entityCond);
    }
}
